# Redux - 03

redux 有着丰富的社区,衍生出了很好用的中间件

  • redux-thunk
  • redux-saga

# redux-thunk

之前学过,reducer为同步过程且只支持纯函数,也就意味着无法在reducer中处理异步操作。

redux-thunk的出现,提供了异步的解决方案。

首先先要引入reudx的applyMiddleware。如果需要支持浏览器redux,还需要引入增强函数compose。

//store/index.js

import {createStore, applyMiddleware, compose} from 'redux'
import thunk from 'redux-thunk'
import reducer from './reducer'

const composeEnhancers =   window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}):compose

const enhancer = composeEnhancers(applyMiddleware(thunk))

createStore(reducer, applyMiddleware(enhancer))

前期工作准备完成,完成demo,在reducer中调用ajax。


// actionCreators.js

export const getListAction = (data) => ({
  type: GET_LIST,
  data
})
export const getList = () => {
    return (dispathc) => {
        axios.post(url).then(res => {
            const action = getListAction(res.data.data)
            dispatch(action)
        })
    }
  
}


// App.js

componentDidMount () {
    const action = getData()
    store.dispatch(action)
}

基础使用,更深奥的东西做项目的时候再慢慢看!

redux-sage同thunk大同小异,再说吧。

# react-redux

react-redux 的出现将组件进行了划分,UI组件和容器组件

# 概述

# UI组件

  • 只负责 UI 的呈现,不带有任何业务逻辑
  • 没有状态(即不使用this.state这个变量)
  • 所有数据都由参数(this.props)
  • 不使用任何 Redux 的 API

const Title = value => <h1>{value}</h1>

因为不含有状态,UI 组件又称为"纯组件",即它纯函数一样,纯粹由参数决定它的值。

# 容器组件

容器组件负责处理所有的业务逻辑,将数据处理好之后提供给UI组件使用

  • 负责管理数据和业务逻辑,不负责 UI 的呈现
  • 带有内部状态
  • 使用 Redux 的 API

# 使用

# connect

该方法用于从UI组件生成容器组件起连接左右。


import {connect} from 'react-redux'

const App = () => {}

export default connect(null, null)(App)

由上方代码可见,connect方法接受两个参数

  • mapStateToProps
  • mapDispatchToProps

前者输入逻辑,将state映射到组件的参数上(props),后者输出逻辑,将用户对组件的操作映射成。Action

# mapStateToProps

常用写法:


const stateToProps = (state) => {
    rerurn {
        value: state.value
    }
}


还可接受第二个参数,代表组件的props

使用props作为参数后,如果容器组件的参数发生变化,也会引发 UI 组件重新渲染。

connect方法可以省略mapStateToProps参数,那样的话,UI 组件就不会订阅Store,就是说 Store 的更新不会引起 UI 组件的更新。

# mapDispatchToProps

常用写法:


const dispatchToProps = (dispatch) => {
    rerurn {
        click () {
            let action = {}
            dispatch(action)
        }
    }
}

# Provider

已经使用了connec生成了UI容易,需要获取state。在index.js中使用Provider将目标组件包裹,其子组件均可获取state。

// index.js
import {Provider} from 'react-redux'
import store from './store'

const Main = {
    <Provider store={store}>
        <App />
    </Provider>
}

reactDOM.render(Main, docoument.getElementById('root'));

再配合无状态组件即可完成。


const App = (props) => {
    let {value} = props
    return (
        <div>{value}</div>
    )
}

const stateToProps = (state) => {
    return {
        value: state.value
    }
}

export default connect(stateToProps)(App)

以上。